#include <algorithm> 
#include <vector> 

template <typename T, typename A> void erase(std::vector<T, A>& container, const T& element) 
{ 
	container.erase( std::remove(container.begin(), container.end(), element), container.end() ); 
} 

template <typename T, typename A, typename P> void erase_if(std::vector<T, A>& container, P predicate) 
{ 
	container.erase( std::remove_if(container.begin(), container.end(), predicate), container.end() ); 
} 


#include <deque> 

template <typename T, typename A> void erase(std::deque<T, A>& container, const T& element) 
{ 
	container.erase( std::remove(container.begin(), container.end(), element), container.end() ); 
} 

template <typename T, typename A, typename P> void erase_if(std::deque<T, A>& container, P predicate) 
{
	container.erase( std::remove_if(container.begin(), container.end(), predicate), container.end() ); 
} 


#include <list> 

template <typename T, typename A> void erase(std::list<T, A>& container, const T& element) 
{ 
	container.remove(element); 
} 

template <typename T, typename A, typename P> void erase_if(std::list<T, A>& container, P predicate) 
{ 
	container.remove_if(predicate); 
} 


#include <forward_list> 

template <typename T, typename A> void erase(std::forward_list<T, A>& container, const T& element) 
{ 
	container.remove(element); 
} 

template <typename T, typename A, typename P> void erase_if(std::forward_list<T, A>& container, P predicate) 
{
	container.remove_if(predicate); 
} 


#include <set> 

template <typename T, typename C, typename A> void erase(std::set<T, C, A>& container, const T& element) 
{ 
	auto it = container.find(element);

	if (it != container.end()) 
		container.erase(it); 
} 

template <typename T, typename C, typename A, typename P> void erase_if(std::set<T, C, A>& container, P predicate) 
{ 
	for (auto it = container.begin(); it != container.end(); )
	{ 
		if (predicate(*it)) container.erase(it++);
		else ++it; 
	} 
} 

template <typename T, typename C, typename A> void erase(std::multiset<T, C, A>& container, const T& element) 
{ 
	auto range = container.equal_range(element); 
	container.erase(range.first, range.second); 
}

template <typename T, typename C, typename A, typename P> void erase_if(std::multiset<T, C, A>& container, P predicate) 
{ 
	for (auto it = container.begin(); it != container.end(); ) 
	{
		if (predicate(*it)) 
			container.erase(it++); 
		else ++it; 
	}
}
